package br.com.timecardforpeon.domain;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import br.com.timecardforpeon.domain.contentvalue.EntryContentValues;
import br.com.timecardforpeon.domain.contentvalue.TimeCard4PeonContentValues;
import br.com.timecardforpeon.util.Util;

public class Entry extends Domain {

	private static final long serialVersionUID = 3852830652185356220L;

	public static final String TABLE_NAME = "entry";
	public static final String COLUMN_CHECK_IN = "check_in";
	public static final String COLUMN_CHECK_OUT = "check_out";
	public static final String COLUMN_DAY_ID = "day_id";
	
	public static final String LIST_BY_DAY_QUERY = "select e.*, d.* from entry e, day d where e.day_id = d.id and d.day = ? order by e.check_in ASC, e.id ASC";
	public static final String LIST_BY_PERIOD_QUERY = "select e.*, d.* from entry e, day d where e.day_id = d.id and date(d.day) >= date(?) and date(d.day) <= date(?) order by e.check_in ASC, e.check_out ASC";

	protected Date checkIn;
	protected Date checkOut;
	protected Day day;

	public Date getCheckIn() {
		return checkIn;
	}

	public void setCheckIn(Date checkIn) {
		this.checkIn = checkIn;
	}

	public Date getCheckOut() {
		return checkOut;
	}

	public void setCheckOut(Date checkOut) {
		this.checkOut = checkOut;
	}

	public Day getDay() {
		return day;
	}

	public void setDay(Day day) {
		this.day = day;
	}
	
	public String getCheckInTime() {
		return Util.getTime(this.checkIn);
	}
	
	public String getCheckOutTime() {
		return Util.getTime(this.checkOut);
	}
	
	public int getTotalMinutes() {
		
		if (this.checkOut == null) {
			return 0;
		}
		
		return (int) (this.checkOut.getTime() - this.checkIn.getTime()) / 1000 / 60;
	}
	
	public String getTotalHoursAsString() {
		return Util.getTotalHours(this.getTotalMinutes());
	}
	
	public void removeValue(CheckType checkType) {
		
		if (CheckType.IN.equals(checkType)) {
			this.checkIn = null;
		}
		else if (CheckType.OUT.equals(checkType)) {
			this.checkOut = null;
		}
	}
	
	public static Map<Day, EntryPerDay> organizeEntriesPerDay(List<Entry> entries) {
		
		Map<Day, EntryPerDay> map = new LinkedHashMap<Day, EntryPerDay>();
		for (Entry entry : entries) {
			
			Day day = entry.getDay();
			if (map.containsKey(day)) {
				map.get(day).addEntry(entry);
				continue;
			}
			
			EntryPerDay entryByDay = new EntryPerDay(day);
			entryByDay.addEntry(entry);
			map.put(day, entryByDay);
		}
		return map;
	}
	
	public static int getMaxEntriesPerDay(Map<Day, EntryPerDay> entriesPerDay) {
		
		int maxEntriesPerDay = 0;
		for (Day day : entriesPerDay.keySet()) {
		
			int entriesLength = entriesPerDay.get(day).getEntries().size();
			
			if (entriesLength > maxEntriesPerDay) {
				maxEntriesPerDay = entriesLength;
			}
		}
		
		return maxEntriesPerDay;
	}
	
	@Override
	public String toString() {
		
		StringBuilder sb = new StringBuilder();
		
		return sb
				.append(Util.getTime(this.checkIn))
				.append(";")
				.append(Util.getTime(this.checkOut))
				.append(";")
				.toString();
	}

	@Override
	public TimeCard4PeonContentValues<Entry> getContentValues() {
		return new EntryContentValues().create(this);
	}

	@Override
	public String getTableName() {
		return TABLE_NAME;
	}

	public static String createTable() {
		return String
				.format("create table %s ("
						+ "id integer primary key autoincrement, %s text, %s text default null, "
						+ "%s integer not null, foreign key (%s) references day (id));",
						TABLE_NAME, COLUMN_CHECK_IN, COLUMN_CHECK_OUT, COLUMN_DAY_ID, COLUMN_DAY_ID);
	}
}